var userService = require('../../services/userService');
var md5 = require('MD5');
var Audits = mongoose.model('backoffice_audits');
var cacheUtil = require('./cacheUtil');
var Users = mongoose.model('user');
var toolUtil = require('./toolUtil');
var adminUsers = mongoose.model('backoffice_adminusers');
var userDevice = mongoose.model('user_device_profile');
var Question = mongoose.model('question');
var neighbourActivity = mongoose.model('activity_neighbour');
var specialTopics = mongoose.model('system_specialTopics');
var fs = require('fs');
var qiniuUtil = require('./qiniuUtil');
var moment = require('moment');
var marketService = require('../../services/marketService');
/*  宝宝树66小区二次改造    add   chenf  20170823   start   */
var Goods = mongoose.model('goods');
/*  宝宝树66小区二次改造    add   chenf  20170823   end   */


/**
 * 对每个消息记录消息的Audit日志;
 */
exports.doAudit = function (req, status) {
    var audit = new Audits();
    var tempStartDateTime = new Date(req.requestStartDataTime);
    var tempEndDateTime = new Date();
    audit.ip = req.ip;
    audit.userId = toolUtil.getUserObjIdByToken(req.query.token ? req.query.token : req.params.token);
    audit.RESTURL = req.url;
    audit.RESTURL_d = req.route.path;
    audit.requestProcessedStatus = status;
    audit.startDateTime = tempStartDateTime;
    audit.endDateTime = tempEndDateTime;
    audit.elapsedMilliSeconds = tempEndDateTime.getTime() - tempStartDateTime.getTime();
    audit.save(function (err, result) {
        if (err) {
            logger.error(err.message)
        } else {
            result._doc.body = req.body;
            exports.putMessageRequestMQ(result);
        }
    });
};

/**
 *  根据用户的对象ID,生成一个token
 *  把token缓冲到memCache中
 */

exports.generateAndCacheToken = function (userObjectId) {
    var token = userObjectId;
    //var token = userObjectId +'-'+ new Date().getTime();
    //cacheUtil.cacheSet(token, userObjectId, function (err, result) {
    //    if (err) {
    //        logger.error('Error happened when token generation and caching for user - ' + userObjectId);
    //    } else {
    //        logger.debug('Successfully for token generation and caching for user - ' + userObjectId);
    //    }
    //}, userTokenExpireSeconds);
    return token;
};

exports.getAndCacheHuanXinToken = function (callback) {
    var key = 'huanXinToken';
    cacheUtil.cacheGet(key, function (err, result) {
        if (result == null) {
            var args = {
                data: huanxinOption,
                headers: {
                    "Content-Type": "application/json"
                }
            };
            restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/token", args, function (data, response) {
                logger.debug(data);
                cacheUtil.cacheSet(key, data.access_token, function (err, result) {
                    if (err) {
                        logger.error('Failed to cache the huanxin token');
                    } else {
                        callback(null, data.access_token);
                    }
                }, data.expires_in - 3600);
            }).on('error', function (err) {
                logger.debug('error:' + err.stack);
            });
        } else {
            callback(null, result);
        }
    })
};

/**
 * 把请求消息放入到message Queue
 * 消息格式为：
 * httpMethod, URL, userID, bodyData, DateTime
 *
 */
exports.putMessageRequestMQ = function (message) {
    auditEx.publish('ex.audit', message);
};

exports.putMessageQAMQ = function (message) {
    if (enbalePush != null && enbalePush == 'Yes') {
        logger.info('push message to q.push.qa');
        mqConnection.publish('q.push.qa', message);
    }
};

exports.putMessageBusinessMQ = function (message) {
    logger.info(message);
    mqConnection.publish('q.business.push', message);
};

exports.putMessageLogMQ = function (message) {
    mqConnection.publish('q.app.log', message);
};

exports.putMessageAppRequestLogMQ = function (message) {
    mqConnection.publish('q.app.request:log', message);
};

/**
 * 往messageQueue中丢入需要向baidu推送的消息
 * 消息的格式为：
 * {
     "baiduToken":   "XXXX",
     "userObjId":    "XXX",
     "messageDesc":  "XXXX"
  }
 *
 */
exports.putMessageBaiduPushMQ = function (message) {
    mqConnection.publish('baiduPushMessage', message);
};

exports.putMessageVerificationCodeMQ = function (message) {
    mqConnection.publish('verificationCodeMessage', message);

};

exports.putMessageLoginOrRegisterLogMQ = function (message) {
    mqConnection.publish('q.log.loginOrRegister', message);
};

exports.putMessageGetuiPushMQ = function (message) {
    mqConnection.publish('getuiPushMessage', message);
};
exports.putMessageTransmissionPushMQ = function (message) {
    mqConnection.publish('q.push.transmission', message);
};
exports.putMessageActivityMQ = function (message) {
    //mqConnection.publish('q.activity.msg.push', message);
};

exports.putMessageThirdPartyImageMQ = function (message) {
    mqConnection.publish('q.thirdParty.image', message);
};

exports.putMessageSmartRankMQ = function (message) {
    //mqConnection.publish('q.question.smart.rank', message)
};

exports.putMessageUserExpMQ = function (message) {
    //mqConnection.publish('q.user.exp', message);
};

exports.putMessageGoodsSmart = function (message) {
    //mqConnection.publish('q.goods.smart', message);
};

exports.pushServiceId = function (communities, serviceId) {
    var content = {
        f: 5,
        q: serviceId
    };
    var pushData = {
        tags: [],
        content: content,
        pushApns: 'no'
    };
    mqConnection.publish('q.push.tag', pushData);
};

/**
 * 根据token去获取对应的用户objId是多少
 */
exports.getUserObjIdByToken = function (userObjId) {
    if (userObjId != null && userObjId.length > 24) {
        userObjId = exports.getUserIdByToken(userObjId);
    }
    return userObjId;
};

exports.setUserByToken = function (token, isInit) {

    if (token.length > 24) {
        token = exports.getUserIdByToken(token);
    }

    userService.findByIdService(token, 100, function (err, user) {
        if (err) {
            logger.error('Exception happened when trying to find user based on user userId...!' + err.message);
        } else {
            cacheUtil.cacheSet(token, JSON.stringify(user), function (err, result) {
                if (err) {
                    logger.error('Failed to cache the user by - ' + err.message);
                } else {
                    logger.debug('Succeeded to cache the user by - ' + token);

                    if (isInit) {
                        //marketService.initSmartGoodsListService(token);
                    }
                }
            }, userDataCacheByTokenExpireSeconds);
        }
    })
};

exports.getUserByToken = function (token, callback, flag) {

    if (flag == 'checkToken') {
        token = exports.getUserIdByToken(token);
    } else {
        if (token.length > 24) {
            token = exports.getUserIdByToken(token);
        }
    }

    cacheUtil.cacheGet(token, function (err, result) {
        if (err) {
            logger.error('Failed to get the user by - ' + token);
            callback(err, null);
        } else {
            try {
                var user = JSON.parse(result);
                if (user == null) {
                    var msg = {
                        "message": noUserErrMessage
                    };
                    callback(msg, null);
                } else if (user.community == null) {
                    var msg = {
                        "message": '未设置小区'
                    };
                    callback(msg, user);
                } else {
                    callback(null, user);
                }
            } catch (e) {
                logger.error(e);
                var msg = {
                    "message": noUserErrMessage
                };
                callback(msg, null);
            }
        }
    });
};

exports.md5Validate = function (deviceId, body) {

    logger.info(body);

    var reqMd5 = body.md5;
    delete body.md5;

    var str = JSON.stringify(body) + deviceId + App_key;

    logger.info(str);
    var nowMd5 = md5(str);
    logger.info(nowMd5);
    return reqMd5 == nowMd5;
};

/**
 * 根据userId获取baiduPushToken
 */

exports.getPushTokenByUserId = function (userId, callback) {
    userService.findPushTokenService(userId, function (err, result) {
        if (err) {
            callback(err, null)
        } else {
            if (result != null) {
                callback(null, result.baiduMessagePushingToken);
            }
        }
    })
};

/**
 * 根据手机号去生成验验证吗，保存在缓冲中；
 */
exports.generateVerificationCode = function (mobilePhone, key) {

    var Num = '';
    for (var j = 0; j < 4; j++) {
        var ran = Math.floor(Math.random() * 10);
        if (j == 0) {
            while (ran == 0) {
                ran = Math.floor(Math.random() * 10);
            }
        }
        Num += ran;
    }
    cacheUtil.cacheSet(key, Num, function (err, result) {
        if (err) {
            logger.error('Failed to generate the verification code for - ' + mobilePhone);
        } else {
            logger.debug('Succeeded to generate the verification code for - ' + mobilePhone);
        }
    }, verificationCodeExpiredSeconds);
    return Num;
};

/* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170907   start */
exports.getRandomNumberByNum = function (number) {

    var Num = '';
    for (var j = 0; j < number; j++) {
        var ran = Math.floor(Math.random() * 10);
        if (j == 0) {
            while (ran == 0) {
                ran = Math.floor(Math.random() * 10);
            }
        }
        Num += ran;
    }
    return Num;
};
/* 宝宝树66小区二期拼团    mod  guo.xiaomin  20170907   end */


/**
 * 图片上传, 最多10张图片
 * 存放在/public/tempImages/objID/timestamp/objID+timestamp+fileName
 * 返回的是一个图片的存放URL的数组
 */

var async = require('async');

exports.uploadImageService = function (objectName, id, req, callback) {

    async.series([

        function (callbackInner) {
            if (req.files.image1 != null) {
                var imageName1 = req.files.image1.name;
                var imagePath1 = req.files.image1.path;

                qiniuUtil.uploadFile(imagePath1, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath1);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image2 != null) {
                var imageName2 = req.files.image2.name;
                var imagePath2 = req.files.image2.path;

                qiniuUtil.uploadFile(imagePath2, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath2);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image3 != null) {
                var imageName3 = req.files.image3.name;
                var imagePath3 = req.files.image3.path;
                qiniuUtil.uploadFile(imagePath3, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath3);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image4 != null) {
                var imageName4 = req.files.image4.name;
                var imagePath4 = req.files.image4.path;
                qiniuUtil.uploadFile(imagePath4, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath4);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image5 != null) {
                var imageName5 = req.files.image5.name;
                var imagePath5 = req.files.image5.path;
                qiniuUtil.uploadFile(imagePath5, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath5);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image6 != null) {
                var imageName6 = req.files.image6.name;
                var imagePath6 = req.files.image6.path;
                qiniuUtil.uploadFile(imagePath6, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath6);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image7 != null) {
                var imageName7 = req.files.image7.name;
                var imagePath7 = req.files.image7.path;
                qiniuUtil.uploadFile(imagePath7, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath7);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image8 != null) {
                var imageName8 = req.files.image8.name;
                var imagePath8 = req.files.image8.path;
                qiniuUtil.uploadFile(imagePath8, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath8);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image9 != null) {
                var imageName9 = req.files.image9.name;
                var imagePath9 = req.files.image9.path;
                qiniuUtil.uploadFile(imagePath9, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath9);
                });
            }
            else {
                return callbackInner(null, null);
            }
        },

        function (callbackInner) {
            if (req.files.image10 != null) {
                var imageName10 = req.files.image10.name;
                var imagePath10 = req.files.image10.path;
                qiniuUtil.uploadFile(imagePath10, function (err, result) {
                    callbackInner(err, result);
                    fs.unlink(imagePath10);
                });
            }
            else {
                return callbackInner(null, null);
            }
        }
    ], callback);
};


exports.getRandomNumArray = function (length, Range) {
    var num = [];
    for (var i = 0; i < length; i++) {
        var val = Math.ceil(Math.random() * Range - 1);
        var isEqu = false;
        for (var idx in num) {
            if (num[idx] == val) {
                isEqu = true;
                break;
            }
        }
        if (isEqu)
            i--;
        else
            num[num.length] = val;
    }
    return num;
};

/**
 * 字符串转16进制
 * @param str
 * @returns {string}
 */
exports.stringToHex = function (str) {
    var val = "";
    for (var i = 0; i < str.length; i++) {
        var v = str.charCodeAt(i).toString(16);
        while (v.length < 4) {
            v = 0 + v;
        }
        val += v;
    }
    return val;
};

/**
 * 判断当前时间是否在某一时间段
 * @param beginTime
 * @param endTime
 * @returns {boolean}
 */
exports.time_range = function (beginTime, endTime) {
    var strb = beginTime.split(":");
    if (strb.length != 2) {
        return false;
    }
    var stre = endTime.split(":");
    if (stre.length != 2) {
        return false;
    }
    var b = new Date();
    var e = new Date();
    var n = new Date();

    b.setHours(strb[0]);
    b.setMinutes(strb[1]);
    e.setHours(stre[0]);
    e.setMinutes(stre[1]);

    if (b.getTime() - e.getTime() >= 0) {
        if (n.getTime() - b.getTime() > 0 || n.getTime() - e.getTime() < 0) {
            return true;
        } else {
            return false;
        }
    } else {
        if (n.getTime() - b.getTime() > 0 && n.getTime() - e.getTime() < 0) {
            return true;
        } else {
            return false;
        }
    }
};


/**
 *  获取抽奖号码
 */
exports.generateLotteryTickets = function (key, callback) {
    redisClient.smembers(key, function (err, value) {
        if (err) throw(err);
        var pool = key + ':pool';
        var discard = key + ':discard';
        if (value.length < 100) {
            redisClient.sunion([key, pool, discard], function (err, value) {
                if (err) throw(err);
                var ran = getLotteryTickets(value, 500);
                redisClient.sadd(key, ran, function (err, result) {
                    redisClient.spop(key, function (err, value) {
                        if (value != null) {
                            redisClient.sadd(pool, value);
                            callback(err, value)
                        }
                    });
                });
            })
        } else {
            redisClient.spop(key, function (err, value) {
                if (value != null) {
                    redisClient.sadd(pool, value);
                    callback(err, value)
                }
            });
        }
    })
};

function getLotteryTickets(c, length) {
    var num = [];
    for (var i = 0; i < length; i++) {

        var val = '';
        for (var j = 0; j < 6; j++) {
            var ran = Math.floor(Math.random() * 10);
            if (j == 0) {
                while (ran == 0) {
                    ran = Math.floor(Math.random() * 10);
                }
            }
            val += ran;
        }
        var isEqu = false;
        for (var idx in num) {
            if (num[idx] == val) {
                isEqu = true;
                break;
            }
        }
        if (contains(c, val)) {
            isEqu = true;
        }
        if (isEqu)
            i--;
        else
            num[num.length] = val;
    }
    return num;
}

function contains(array, obj) {
    var i = array.length;
    while (i--) {
        if (array[i] === obj) {
            return true;
        }
    }
    return false;
}

/**
 * 小6客服发消息
 * @param user
 * @param message
 */
exports.pushCustomerServiceMessage = function (user, message) {
    toolUtil.getAndCacheHuanXinToken(function (err, token) {

        Users.findOne({'huanxinUserName': '66customerservice'}, '_id images huanxinUserName', function (err, result) {
            var args = {
                data: {
                    "target_type": "users",
                    "target": [user.huanxinUserName],
                    "msg": {
                        "type": "txt",
                        "msg": message
                    },
                    "from": 'superservice',
                    "ext": {           //扩展属性, 由app自己定义.可以没有这个字段，但是如果有，值不能是“ext:null“这种形式，否则出错
                        "nickName": "小6客服",
                        "avatar": result.images[0].imageURL,
                        "objId": result._id
                    }
                },
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": "Bearer " + token
                }
            };
            restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/messages", args, function (data, response) {
                logger.debug(data);
            }).on('error', function (err) {
                logger.error('sendMessageByCustomService' + err.message);
            });
        });

    });
};

exports.deleteImage = function (fileIds) {
    async.each(fileIds, function (fileId, callbackInner) {
        if (fileId != null) {
            var id = fileId.substr(1);
            fdfsClient.del(id, callbackInner);
        } else {
            callbackInner();
        }
    }, function (err) {
        logger.debug('----deleteImage');
    })
};

exports.hessianInvokeAddScore = function (token, action, score, callback, vCode) {

    Users.findOne({_id: token + ''}, function (err, user) {

        if (err) {
            logger.error('hessianInvokeAddScore----1' + err.message);
            callback(null);
        } else {
            var userRole = 1;

            if (user.userType == 'talent') {
                userRole = 2;
            }

            var arg = {
                userId: user._id + '',
                userRole: userRole,
                userActionType: action
            };

            if (vCode != null) {
                arg.vCode = vCode
            }

            if (score != null) {
                arg.addScore = score
            }

            arg.__type__ = 'com.neighborhoods.service.score.dto.ScoreAddRequestDto';

            scoreProxy.invoke('addScore', [arg], function (err, reply) {
                try {
                    if (err) {
                        logger.error('hessianInvokeAddScore-----2' + err.message);
                        callback(null);
                    } else {
                        var data = JSON.parse(decodeURIComponent(reply));
                        if (data.status != 0) {
                            logger.error('hessianInvokeAddScore----3' + data.status + '----' + data.msg);
                            callback(null);
                        } else {
                            callback(data.data);
                        }
                    }
                } catch (e) {
                    logger.error('hessianInvokeAddScore---4' + e);
                    callback(null);
                }
            });
        }
    });
};


exports.hessianManualAddScore = function (token, action, score, reason, callback) {

    if (reason != null)
        reason = reason.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '');

    Users.findOne({_id: token + ''}, function (err, user) {

        if (err) {
            logger.error('hessianInvokeAddScore----1' + err.message);
            callback(null);
        } else {
            var userRole = 1;

            if (user.userType == 'talent') {
                userRole = 2;
            }

            var arg = {
                userId: user._id + '',
                userRole: userRole,
                addScoreReason: reason,
                userActionType: action
            };

            if (score != null) {
                arg.addScore = score
            }

            arg.__type__ = 'com.neighborhoods.service.score.dto.ScoreAddRequestDto';

            scoreProxy.invoke('addScore', [arg], function (err, reply) {
                try {
                    if (err) {
                        logger.error('hessianInvokeAddScore-----2' + err.message);
                        callback(null);
                    } else {
                        var data = JSON.parse(decodeURIComponent(reply));
                        if (data.status != 0) {
                            logger.error('hessianInvokeAddScore----3' + data.status + '----' + data.msg);
                            callback(null);
                        } else {
                            callback(data.data);
                        }
                    }
                } catch (e) {
                    logger.error('hessianInvokeAddScore---4' + e);
                    callback(null);
                }
            });
        }
    });
};


/**
 * 获取邀请码
 * @param callback
 */
exports.getInvitationCode = function (callback) {
    var codeKey = 'app:invitation:code';
    var indexKey = 'app:invitation:index';

    redisClient.scard(codeKey, function (err, count) {
        if (err) throw(err);
        if (count < 100) {
            redisClient.get(indexKey, function (err, value) {
                var index = value == null ? '10000' : value;
                if (index == 'over') {
                    redisClient.spop(codeKey, callback);
                } else {
                    redisClient.sadd(codeKey, createInvitationCodeByIndex(index), function (err, result) {
                        if (index == '90000') {
                            redisClient.set(indexKey, 'over');
                        } else {
                            redisClient.set(indexKey, Number(index) + 10000);
                        }
                        redisClient.spop(codeKey, callback);
                    });
                }
            });
        } else {
            redisClient.spop(codeKey, callback);
        }
    })
};

function createInvitationCodeByIndex(index) {
    index = Number(index);
    var codeArray = [];
    for (var i = index; i <= index + 9999; i++) {
        codeArray.push(i);
    }
    return codeArray;
}

exports.getPromotionCode = function (length, callback) {
    var key = 'app:promotion:code';

    redisClient.smembers(key, function (err, value) {
        var ran = getLotteryTickets(value, length);
        redisClient.sadd(key, ran, function (err, result) {
            callback(err, ran);
        });
    });
};

/**
 * 根据小区id获取客服信息
 * @param communityId
 * @param callback
 */
exports.getCustomerServiceByCommunityId = function (communityId, callback) {

    adminUsers.findOne({
        communities: communityId,
        role: 'Service',
        signed: true
    }).populate('appuser', 'images nickName huanxinUserName')
        .exec(function (err, result) {
            if (result != null) {
                callback(err, result.appuser);
            } else {
                Users.findOne({huanxinUserName: '66customerservice'}, 'images nickName huanxinUserName', function (err, result) {
                    callback(err, result);
                })
            }
        })
};

exports.filteringSensitiveWords = function (id, replyId, replyDesc, category, callback) {

    if (replyDesc == null || replyDesc == '') {
        callback(null, '');
    } else {
        restClient.get('http://' + RecommendHost + ':8002?data=' + replyDesc, function (data, response) {
            if (response.statusCode == 200 && data != null && data != 'unknown' && data != '') {
                try {
                    if (typeof data == 'string') {
                        data = JSON.parse(data)
                    }
                    var sensitive = data.sensitive;
                    if (sensitive != null) {
                        replyDesc = sensitive;

                        if (category == 'question') {
                            Question.update({
                                _id: id,
                                'replies._id': replyId
                            }, {'replies.$.replyDesc': replyDesc}).exec();
                        } else if (category == 'activity') {
                            neighbourActivity.update({
                                _id: id,
                                'replies._id': replyId
                            }, {'replies.$.replyDesc': replyDesc}).exec();
                        } else if (category == 'topic') {
                            specialTopics.update({
                                _id: id,
                                'comments._id': replyId
                            }, {'comments.$.commentDesc': replyDesc}).exec();
                        }

                        callback(null, replyDesc);
                    } else {
                        callback(null, replyDesc);
                    }
                } catch (e) {
                    logger.error('filteringSensitiveWords----' + data);
                    callback(null, replyDesc);
                }
            } else {
                callback(null, replyDesc);
            }
        }).on('error', function (err) {
            logger.error(err.message);
            callback(null, replyDesc);
        });
    }
};


exports.transformNumber = function (number, flag) {
    if (number == null || Number(number) < 0) {
        number = 0;
    }

    if (number == 0) {
        return flag ? '0' : '';
    } else {
        return number >= 1000 ? Math.round(number / 100) / 10 + 'k' : number + '';
    }
};

exports.getExpireTime = function () {
    var date = moment().startOf("day").add(1, 'day');
    return Math.round(date.toDate() / 1000 - new Date().getTime() / 1000)
};

exports.getUserLevel = function (exp) {
    if (exp == null) {
        return 1;
    } else {
        var level = Math.floor(Math.sqrt(exp / 166)) + 1;
        return level > 12 ? 12 : level
    }
};

exports.changeUserStatistics = function (userId, communityId, field, value) {
    var key = 'user:statistics:' + userId + ':' + communityId;

    redisClient.HINCRBY(key, field, value);
};
/*  宝宝树66小区二次改造    mod   guo.xiaomin  20170907   start   */
exports.changeUserStatisticsNew = function (userId, field, value) {
    var key = 'user:statistics:' + userId ;

    redisClient.HMGET(key, 'goods', "questionReply", function(err, result){
        if(result[0] != null && result[1] != null) {
            redisClient.HINCRBY(key, field, value);
        } else {
            if(result[0] == null) {
                Goods.count({createdBy: userId, isValid: true}, function (err, count) {
                    redisClient.HSET(key, 'goods', count);
                });
            } else {
                if(field == 'goods') {
                    redisClient.HINCRBY(key, 'goods', value);
                }
            }
            if(result[1] == null) {
                Question.find({'replies.repliedBy': userId,isValid:true}, function (err, result) {
                    var questionReply = 0;
                    for(var i=0;i<result.length;i++){
                        var replies = result[i].replies;
                        for(var q=0;q<replies.length;q++){
                            var repliedBy = replies[q]._doc.repliedBy;
                            if(repliedBy == userId){
                                questionReply +=1;
                            }
                        }
                    }
                    redisClient.HSET(key, "questionReply", questionReply);
                });
            } else {
                if(field == 'questionReply') {
                    redisClient.HINCRBY(key, "questionReply", value);
                }
            }
        }
    });
};
/*  宝宝树66小区二次改造    mod   guo.xiaomin  20170907   end   */
exports.getUserStatistics = function (userId, communityId, callback) {
    var key = 'user:statistics:' + userId + ':' + communityId;

    redisClient.HGETALL(key, function (err, result) {
        if (result == null) {
            callback(null, {
                question: 0,
                questionReply: 0,
                goods: 0,
                goodsReply: 0,
                adoptedReply: 0,
                thankedReply: 0,
                questionPraise: 0
            })
        } else {
            callback(null, result);
        }
    });
};
/*   宝宝树66小区二次改造    mod   guo.xiaomin  20170907   start   个人页数据统计修改  */
exports.getUserStatisticsNew = function (userId,callback) {
    var key = 'user:statistics:' + userId ;

    // 从DB里面取数据-临时方案(DB的数据与redis数据可能不一致)
    async.parallel([
        function (callbackInner) {
            Goods.count({createdBy: userId, isValid: true}, function (err, count) {
                redisClient.HSET(key, 'goods', count);
                callbackInner(null, count);
            });
        },
        function (callbackInner) {
            Question.find({'replies.repliedBy': userId, isValid: true}, function (err, result) {
                var questionReply = 0;
                for (var i = 0; i < result.length; i++) {
                    var replies = result[i].replies;
                    for (var q = 0; q < replies.length; q++) {
                        var repliedBy = replies[q]._doc.repliedBy;
                        if (repliedBy == userId) {
                            questionReply += 1;
                        }
                    }
                }
                redisClient.HSET(key, "questionReply", questionReply);
                callbackInner(null, questionReply);
            });
        }
    ], function (err, result) {
        callback(null, {goods: result[0], questionReply: result[1]});
    });


    // 从redis里面取数据-最终方案(需要先把redis的数据与DB数据保持一致)
    // redisClient.HMGET(key, 'goods', "questionReply", function(err, result){
    //     if(result[0] != null && result[1] != null) {
    //         callback(null, {goods: result[0], questionReply: result[1]});
    //     } else {
    //         async.parallel([
    //             function (callbackInner) {
    //                 if(result[0] != null) {
    //                     callbackInner(null, result[0]);
    //                 } else {
    //                     Goods.count({createdBy: userId, isValid: true}, function (err, count) {
    //                         redisClient.HSET(key, 'goods', count);
    //                         callbackInner(null, count);
    //                     });
    //                 }
    //             },
    //             function (callbackInner) {
    //                 if(result[1] != null) {
    //                     callbackInner(null, result[1]);
    //                 } else {
    //                     Question.find({'replies.repliedBy': userId, isValid: true}, function (err, result) {
    //                         var questionReply = 0;
    //                         for (var i = 0; i < result.length; i++) {
    //                             var replies = result[i].replies;
    //                             for (var q = 0; q < replies.length; q++) {
    //                                 var repliedBy = replies[q]._doc.repliedBy;
    //                                 if (repliedBy == userId) {
    //                                     questionReply += 1;
    //                                 }
    //                             }
    //                         }
    //                         redisClient.HSET(key, "questionReply", questionReply);
    //                         callbackInner(null, questionReply);
    //                     });
    //                 }
    //             }
    //         ], function (err, result) {
    //             callback(null, {goods: result[0], questionReply: result[1]});
    //         });
    //     }
    // });

    // async.series([
    //    function (callbackInner) {
    //         Goods.count({createdBy: userId, isValid: true}, function (err, count) {
    //             goods = count;
    //             callbackInner();
    //         })
    //     },
    //    function (callbackInner) {
    //         Question.find({'replies.repliedBy': userId,isValid:true}, function (err, result) {
    //             for(var i=0;i<result.length;i++){
    //                 var replies = result[i].replies;
    //                 for(var q=0;q<replies.length;q++){
    //                     var repliedBy = replies[q]._doc.repliedBy;
    //                     if(repliedBy == userId){
    //                         questionReply +=1;
    //                     }
    //                 }
    //             }
    //             callbackInner();
    //         })
    //    },
    //    function (callbackInner) {
    //         redisClient.HEXISTS(key,"goods",function(err,flg){
    //             if(flg == 0) {
    //                 redisClient.HSET(key, 'goods', goods);
    //             }else{
    //                 redisClient.HGET(key, "goods",function (err, result){
    //                     if(result == 0){
    //                         redisClient.HSET(key, 'goods', goods);
    //                     }
    //                 });
    //             }
    //             callbackInner();
    //         })
    //    },
    //    function (callbackInner) {
    //         redisClient.HEXISTS(key,"questionReply",function(err,flg){
    //          if(flg == 0){
    //             redisClient.HSET(key, "questionReply", questionReply);
    //          }else {
    //              redisClient.HGET(key, "questionReply",function (err, result){
    //                  if(result == 0){
    //                      redisClient.HSET(key, "questionReply", questionReply);
    //                  }
    //              });
    //          }
    //             callbackInner();
    //          })
    //
    //    },
    //    function (callbackInner) {
    //         redisClient.HGETALL(key, function (err, result) {
    //             if (result == null) {
    //                 callbackInner(null, {
    //                     question: 0,
    //                     questionReply: 0,
    //                     goods: 0,
    //                     goodsReply: 0,
    //                     adoptedReply: 0,
    //                     thankedReply: 0,
    //                     questionPraise: 0
    //                 })
    //             } else {
    //                 callbackInner(null, result);
    //             }
    //         });
    //    }
    // ], function (err, result) {
    //     callback(null, result[4]);
    // })
};
/*  宝宝树66小区二次改造    mod   guo.xiaomin  20170907   end   个人页数据统计修改  */
var crypto = require('crypto');

var cipheriv = function (en, code, data) {
    try {
        var buf1 = en.update(data, code), buf2 = en.final();
        var r = new Buffer(buf1.length + buf2.length);
        buf1.copy(r);
        buf2.copy(r, buf1.length);
        return r;
    } catch (e) {
        return 'hex'
    }
};

exports.getUserTokenById = function (userId) {
    userId = userId + '';
    return cipheriv(crypto.createCipher('des', new Buffer('xiaoqu')), 'utf8', userId).toString('hex');
};

exports.getUserIdByToken = function (token) {
    return cipheriv(crypto.createDecipher('des', new Buffer('xiaoqu')), 'hex', token).toString('utf8');
};

/*  宝宝树66小区二次改造    add   guo.xiaomin  20170926   start   */
// 取得客户端IP地址
exports.getClientIp = function (req) {

    // 1120-commit-master
    logger.debug(req.headers['x-forwarded-for'] + "@req.headers['x-forwarded-for']");
    logger.debug(req.connection.remoteAddress + "@req.connection.remoteAddress");
    logger.debug(req.socket.remoteAddress + "@req.socket.remoteAddress");

    return req.headers['x-forwarded-for'] ||
        req.connection.remoteAddress ||
        req.socket.remoteAddress ||
        req.connection.socket.remoteAddress;
};
/*  宝宝树66小区二次改造    add   guo.xiaomin  20170926   end   */

exports.isNowBiggerThanOldGeetestEndDate = function() {
    // 全局参数
    if(oldGeetestEndDate) {
        var temp = new Date(moment(oldGeetestEndDate, "YYYY-MM-DD").format()).getTime();
        if(new Date().getTime() > temp) {
            logger.debug("isNowBiggerThanOldGeetestEndDate..." + true);
            return true;
        } else {
            logger.debug("isNowBiggerThanOldGeetestEndDate..." + false);
            return false;
        }
    } else {
        logger.error("全局参数没有，请修改配置文件...");
        return false;
    }
};

/* 宝宝树66小区 sprint5 66小区APP"我的"页面 新增我的拼团收藏功能 add wangcan 20171117 start */
// base64解码
exports.encodeAtoB = function (r) {
    var e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var o = String(r).replace(/=+$/, "");
    if (o.length % 4 == 1)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");
    for (var n, a, i = 0, c = 0, d = ""; a = o.charAt(c++); ~a && (n = i % 4 ? 64 * n + a : a, i++ % 4) ? d += String.fromCharCode(255 & n >> (-2 * i & 6)) : 0)a = e.indexOf(a);
    return d;
};
/* 宝宝树66小区 sprint5 66小区APP"我的"页面 新增我的拼团收藏功能 add wangcan 20171117 start */

/*  宝宝树66小区sprint4    add   66后台订单总佣金.查询 wangcan  20171110  start   */
// 去除数组中重复的数据
exports.arrayDislodgeRepeat = function (tempArr) {
    var retArr = [];
    var tempObj = {};
    for (var i = 0, length = tempArr.length; i < length; i++) {
        if (!tempObj[tempArr[i].toString()]) {
            retArr.push(tempArr[i]);
            tempObj[tempArr[i].toString()] = 1;
        }
    }
    return retArr;
};
/*  宝宝树66小区sprint4    add   66后台订单总佣金.查询 wangcan  20171110  end   */

/* 宝宝树66小区 sprint6 小区大使业绩页面 新增结算历史明细和佣金订单一览页面 add wangcan 20171208 start */
// 销售类型 0-自营 1-非自营
exports.getItemSaleTypeName = function (itemSaleType) {
    if(itemSaleType == 0) {
        return "自营";
    } else if(itemSaleType == 1) {
        return "非自营";
    } else {
        return null;
    }
};

//是否海淘商品,1-否，2-是，默认1
exports.getWavesSignName = function (wavesSign) {
    if(wavesSign == 1) {
        return "非海淘";
    } else if(wavesSign == 2) {
        return "海淘";
    } else {
        return null;
    }
};

// 是否标品 0 非标品  1标品  -1未设置
exports.getStandardName = function (standard) {
    if(standard == 0) {
        return "非标品";
    } else if(standard == 1) {
        return "标品";
    } else if(standard == -1) {
        return "未设置";
    } else {
        return null;
    }
};

// 订单佣金类型 1-分享 2-自购 3-小区
exports.getOrderCommissionTypeName = function (tempType) {
    var str = '';
    if (tempType == 1) {
        str = '分享';
    } else if (tempType == 2) {
        str = '自购';
    } else if (tempType == 3) {
        str = '小区';
    }
    return str;
}
/* 宝宝树66小区 sprint6 小区大使业绩页面 新增结算历史明细和佣金订单一览页面 add wangcan 20171208 end */